import {
  Controller,
  Get,
  Post,
  Put,
  Delete,
  Param,
  Body,
  Query,
} from "@nestjs/common";
import { RedisService } from "../services/redis.service";

@Controller("redis-test")
export class RedisTestController {
  constructor(private readonly redisService: RedisService) {}

  // 测试连接
  @Get("ping")
  async ping() {
    try {
      const result = await this.redisService.ping();
      return {
        success: true,
        message: "Redis连接成功",
        data: result,
        timestamp: new Date().toISOString(),
      };
    } catch (error) {
      return {
        success: false,
        message: "Redis连接失败",
        error: (error as Error).message,
        timestamp: new Date().toISOString(),
      };
    }
  }

  // 获取Redis信息
  @Get("info")
  async getInfo() {
    try {
      const info = await this.redisService.info();
      return {
        success: true,
        message: "获取Redis信息成功",
        data: info,
        timestamp: new Date().toISOString(),
      };
    } catch (error) {
      return {
        success: false,
        message: "获取Redis信息失败",
        error: (error as Error).message,
        timestamp: new Date().toISOString(),
      };
    }
  }

  // 获取数据库大小
  @Get("dbsize")
  async getDbSize() {
    try {
      const size = await this.redisService.dbsize();
      return {
        success: true,
        message: "获取数据库大小成功",
        data: size,
        timestamp: new Date().toISOString(),
      };
    } catch (error) {
      return {
        success: false,
        message: "获取数据库大小失败",
        error: (error as Error).message,
        timestamp: new Date().toISOString(),
      };
    }
  }

  // 设置键值对
  @Post("set")
  async setKey(@Body() body: { key: string; value: string; ttl?: number }) {
    try {
      const { key, value, ttl } = body;
      const result = await this.redisService.set(key, value, ttl);
      return {
        success: true,
        message: "设置键值对成功",
        data: { key, value, ttl, result },
        timestamp: new Date().toISOString(),
      };
    } catch (error) {
      return {
        success: false,
        message: "设置键值对失败",
        error: (error as Error).message,
        timestamp: new Date().toISOString(),
      };
    }
  }

  // 获取值
  @Get("get/:key")
  async getKey(@Param("key") key: string) {
    try {
      const value = await this.redisService.get(key);
      return {
        success: true,
        message: "获取值成功",
        data: { key, value },
        timestamp: new Date().toISOString(),
      };
    } catch (error) {
      return {
        success: false,
        message: "获取值失败",
        error: (error as Error).message,
        timestamp: new Date().toISOString(),
      };
    }
  }

  // 删除键
  @Delete("del/:key")
  async deleteKey(@Param("key") key: string) {
    try {
      const result = await this.redisService.del(key);
      return {
        success: true,
        message: "删除键成功",
        data: { key, result },
        timestamp: new Date().toISOString(),
      };
    } catch (error) {
      return {
        success: false,
        message: "删除键失败",
        error: (error as Error).message,
        timestamp: new Date().toISOString(),
      };
    }
  }

  // 检查键是否存在
  @Get("exists/:key")
  async checkKeyExists(@Param("key") key: string) {
    try {
      const exists = await this.redisService.exists(key);
      return {
        success: true,
        message: "检查键存在性成功",
        data: { key, exists: exists === 1 },
        timestamp: new Date().toISOString(),
      };
    } catch (error) {
      return {
        success: false,
        message: "检查键存在性失败",
        error: (error as Error).message,
        timestamp: new Date().toISOString(),
      };
    }
  }

  // 设置过期时间
  @Put("expire/:key")
  async setExpire(
    @Param("key") key: string,
    @Query("seconds") seconds: string
  ) {
    try {
      const ttl = parseInt(seconds, 10);
      const result = await this.redisService.expire(key, ttl);
      return {
        success: true,
        message: "设置过期时间成功",
        data: { key, ttl, result },
        timestamp: new Date().toISOString(),
      };
    } catch (error) {
      return {
        success: false,
        message: "设置过期时间失败",
        error: (error as Error).message,
        timestamp: new Date().toISOString(),
      };
    }
  }

  // 获取剩余过期时间
  @Get("ttl/:key")
  async getTtl(@Param("key") key: string) {
    try {
      const ttl = await this.redisService.ttl(key);
      return {
        success: true,
        message: "获取剩余过期时间成功",
        data: { key, ttl },
        timestamp: new Date().toISOString(),
      };
    } catch (error) {
      return {
        success: false,
        message: "获取剩余过期时间失败",
        error: (error as Error).message,
        timestamp: new Date().toISOString(),
      };
    }
  }

  // 哈希表操作 - 设置字段
  @Post("hset")
  async hsetField(@Body() body: { key: string; field: string; value: string }) {
    try {
      const { key, field, value } = body;
      const result = await this.redisService.hset(key, field, value);
      return {
        success: true,
        message: "设置哈希表字段成功",
        data: { key, field, value, result },
        timestamp: new Date().toISOString(),
      };
    } catch (error) {
      return {
        success: false,
        message: "设置哈希表字段失败",
        error: (error as Error).message,
        timestamp: new Date().toISOString(),
      };
    }
  }

  // 哈希表操作 - 获取字段
  @Get("hget/:key/:field")
  async hgetField(@Param("key") key: string, @Param("field") field: string) {
    try {
      const value = await this.redisService.hget(key, field);
      return {
        success: true,
        message: "获取哈希表字段成功",
        data: { key, field, value },
        timestamp: new Date().toISOString(),
      };
    } catch (error) {
      return {
        success: false,
        message: "获取哈希表字段失败",
        error: (error as Error).message,
        timestamp: new Date().toISOString(),
      };
    }
  }

  // 哈希表操作 - 获取所有字段
  @Get("hgetall/:key")
  async hgetAll(@Param("key") key: string) {
    try {
      const fields = await this.redisService.hgetall(key);
      return {
        success: true,
        message: "获取哈希表所有字段成功",
        data: { key, fields },
        timestamp: new Date().toISOString(),
      };
    } catch (error) {
      return {
        success: false,
        message: "获取哈希表所有字段失败",
        error: (error as Error).message,
        timestamp: new Date().toISOString(),
      };
    }
  }

  // 列表操作 - 左推入
  @Post("lpush")
  async lpushValue(@Body() body: { key: string; value: string }) {
    try {
      const { key, value } = body;
      const result = await this.redisService.lpush(key, value);
      return {
        success: true,
        message: "左推入列表成功",
        data: { key, value, result },
        timestamp: new Date().toISOString(),
      };
    } catch (error) {
      return {
        success: false,
        message: "左推入列表失败",
        error: (error as Error).message,
        timestamp: new Date().toISOString(),
      };
    }
  }

  // 列表操作 - 获取范围
  @Get("lrange/:key")
  async lrangeValues(
    @Param("key") key: string,
    @Query("start") start: string = "0",
    @Query("stop") stop: string = "-1"
  ) {
    try {
      const startIndex = parseInt(start, 10);
      const stopIndex = parseInt(stop, 10);
      const values = await this.redisService.lrange(key, startIndex, stopIndex);
      return {
        success: true,
        message: "获取列表范围成功",
        data: { key, start: startIndex, stop: stopIndex, values },
        timestamp: new Date().toISOString(),
      };
    } catch (error) {
      return {
        success: false,
        message: "获取列表范围失败",
        error: (error as Error).message,
        timestamp: new Date().toISOString(),
      };
    }
  }

  // 集合操作 - 添加成员
  @Post("sadd")
  async saddMember(@Body() body: { key: string; member: string }) {
    try {
      const { key, member } = body;
      const result = await this.redisService.sadd(key, member);
      return {
        success: true,
        message: "添加集合成员成功",
        data: { key, member, result },
        timestamp: new Date().toISOString(),
      };
    } catch (error) {
      return {
        success: false,
        message: "添加集合成员失败",
        error: (error as Error).message,
        timestamp: new Date().toISOString(),
      };
    }
  }

  // 集合操作 - 获取所有成员
  @Get("smembers/:key")
  async getSetMembers(@Param("key") key: string) {
    try {
      const members = await this.redisService.smembers(key);
      return {
        success: true,
        message: "获取集合所有成员成功",
        data: { key, members },
        timestamp: new Date().toISOString(),
      };
    } catch (error) {
      return {
        success: false,
        message: "获取集合所有成员失败",
        error: (error as Error).message,
        timestamp: new Date().toISOString(),
      };
    }
  }

  // 有序集合操作 - 添加成员
  @Post("zadd")
  async zaddMember(
    @Body() body: { key: string; score: number; member: string }
  ) {
    try {
      const { key, score, member } = body;
      const result = await this.redisService.zadd(key, score, member);
      return {
        success: true,
        message: "添加有序集合成员成功",
        data: { key, score, member, result },
        timestamp: new Date().toISOString(),
      };
    } catch (error) {
      return {
        success: false,
        message: "添加有序集合成员失败",
        error: (error as Error).message,
        timestamp: new Date().toISOString(),
      };
    }
  }

  // 有序集合操作 - 获取范围
  @Get("zrange/:key")
  async zrangeMembers(
    @Param("key") key: string,
    @Query("start") start: string = "0",
    @Query("stop") stop: string = "-1"
  ) {
    try {
      const startIndex = parseInt(start, 10);
      const stopIndex = parseInt(stop, 10);
      const members = await this.redisService.zrange(
        key,
        startIndex,
        stopIndex
      );
      return {
        success: true,
        message: "获取有序集合范围成功",
        data: { key, start: startIndex, stop: stopIndex, members },
        timestamp: new Date().toISOString(),
      };
    } catch (error) {
      return {
        success: false,
        message: "获取有序集合范围失败",
        error: (error as Error).message,
        timestamp: new Date().toISOString(),
      };
    }
  }

  // 发布消息
  @Post("publish")
  async publishMessage(@Body() body: { channel: string; message: string }) {
    try {
      const { channel, message } = body;
      const result = await this.redisService.publish(channel, message);
      return {
        success: true,
        message: "发布消息成功",
        data: { channel, message, result },
        timestamp: new Date().toISOString(),
      };
    } catch (error) {
      return {
        success: false,
        message: "发布消息失败",
        error: (error as Error).message,
        timestamp: new Date().toISOString(),
      };
    }
  }

  // 获取所有键
  @Get("keys/:pattern")
  async getKeys(@Param("pattern") pattern: string) {
    try {
      const keys = await this.redisService.keys(pattern);
      return {
        success: true,
        message: "获取键列表成功",
        data: { pattern, keys, count: keys.length },
        timestamp: new Date().toISOString(),
      };
    } catch (error) {
      return {
        success: false,
        message: "获取键列表失败",
        error: (error as Error).message,
        timestamp: new Date().toISOString(),
      };
    }
  }

  // 清空数据库
  @Delete("flushdb")
  async flushDatabase() {
    try {
      const result = await this.redisService.flushdb();
      return {
        success: true,
        message: "清空数据库成功",
        data: { result },
        timestamp: new Date().toISOString(),
      };
    } catch (error) {
      return {
        success: false,
        message: "清空数据库失败",
        error: (error as Error).message,
        timestamp: new Date().toISOString(),
      };
    }
  }

  // 综合测试
  @Get("test-all")
  async testAll() {
    try {
      const results = {
        ping: await this.redisService.ping(),
        dbsize: await this.redisService.dbsize(),
        info: await this.redisService.info(),
      };

      return {
        success: true,
        message: "综合测试成功",
        data: results,
        timestamp: new Date().toISOString(),
      };
    } catch (error) {
      return {
        success: false,
        message: "综合测试失败",
        error: (error as Error).message,
        timestamp: new Date().toISOString(),
      };
    }
  }
}
